package io.gitee.macxiang.sql.wapper;

import java.util.List;

import io.gitee.macxiang.utils.utils;

/** SQL的WHERE条件语句构造器
 * @param <S> 数据库操作where条件构造器关联实体类
 */
public class WhereField<S extends BaseWhere> {
  final S where;
  final public String sqlName;

  /**数据库操作
   * @param where   服务自身this
   */
  public WhereField(S where, String sqlName) {
    super();
    this.where = where;
    this.sqlName = sqlName;
  }

  /**设置单个字段的条件: IS NULL
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S isNull(Boolean isOr) {
    where.isNull(sqlName, isOr);
    return where;
  }

  /**设置单个字段的条件: IS NULL
   * @return 返回自身.方便链式操作
   */
  public S isNull() {
    where.isNull(sqlName, false);
    return where;
  }

  /**设置单个字段的条件: IS NOT NULL
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S isNotNull(Boolean isOr) {
    where.isNotNull(sqlName, isOr);
    return where;
  }

  /**设置单个字段的条件: IS NOT NULL
   * @return 返回自身.方便链式操作
   */
  public S isNotNull() {
    where.isNotNull(sqlName, false);
    return where;
  }

  /**设置单个字段的条件: =
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S eqSQL(String value, Boolean isOr) {
    where.eq(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: =
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S eqSQL(String value) {
    return eqSQL(value, false);
  }

  /**设置单个字段的条件: =
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S eq(Object value, Boolean isOr) {
    return eqSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: =
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S eq(Object value) {
    return eq(value, false);
  }

  /**设置单个字段的条件: 不等于(&lt;&gt;)
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S neSQL(String value, Boolean isOr) {
    where.ne(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: 不等于(&lt;&gt;)
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S neSQL(String value) {
    return neSQL(value, false);
  }

  /**设置单个字段的条件: 不等于(&lt;&gt;)
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S ne(Object value, Boolean isOr) {
    return neSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: 不等于(&lt;&gt;)
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S ne(Object value) {
    return ne(value, false);
  }

  /**设置单个字段的条件: 大于(&gt;)
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S gtSQL(String value, Boolean isOr) {
    where.gt(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: 大于(&gt;)
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S gtSQL(String value) {
    return gtSQL(value, false);
  }

  /**设置单个字段的条件: 大于(&gt;)
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S gt(Object value, Boolean isOr) {
    return gtSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: 大于(&gt;)
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S gt(Object value) {
    return gt(value, false);
  }

  /**设置单个字段的条件: 大于等于(&gt;=)
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S geSQL(String value, Boolean isOr) {
    where.ge(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: 大于等于(&gt;=)
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S geSQL(String value) {
    return geSQL(value, false);
  }

  /**设置单个字段的条件: 大于等于(&gt;=)
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S ge(Object value, Boolean isOr) {
    return geSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: 大于等于(&gt;=)
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S ge(Object value) {
    return ge(value, false);
  }

  /**设置单个字段的条件: 小于(&lt;)
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S ltSQL(String value, Boolean isOr) {
    where.lt(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: 小于(&lt;)
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S ltSQL(String value) {
    return ltSQL(value, false);
  }

  /**设置单个字段的条件: 小于(&lt;)
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S lt(Object value, Boolean isOr) {
    return ltSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: 小于(&lt;)
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S lt(Object value) {
    return lt(value, false);
  }

  /**设置单个字段的条件: 小于等于(&lt;=)
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S leSQL(String value, Boolean isOr) {
    where.le(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: 小于等于(&lt;=)
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S leSQL(String value) {
    return leSQL(value, false);
  }

  /**设置单个字段的条件: 小于等于(&lt;=)
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S le(Object value, Boolean isOr) {
    return leSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: 小于等于(&lt;=)
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S le(Object value) {
    return le(value, false);
  }

  /**设置单个字段的条件: BETWEEN
   * @param start 起始值; 值为null时 此条件无效
   * @param end   结束值; 值为null时 此条件无效
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S between(Object start, Object end, Boolean isOr) {
    where.between(sqlName, start, end, isOr);
    return where;
  }

  /**设置单个字段的条件: BETWEEN
   * @param start 起始值; 值为null时 此条件无效
   * @param end   结束值; 值为null时 此条件无效
   * @return 返回自身.方便链式操作
   */
  public S between(Object start, Object end) {
    return between(start, end, false);
  }

  /**设置单个字段的条件: NOT BETWEEN
   * @param start 起始值; 值为null时 此条件无效
   * @param end   结束值; 值为null时 此条件无效
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notBetween(Object start, Object end, Boolean isOr) {
    where.notBetween(sqlName, start, end, isOr);
    return where;
  }

  /**设置单个字段的条件: NOT BETWEEN
   * @param start 起始值; 值为null时 此条件无效
   * @param end   结束值; 值为null时 此条件无效
   * @return 返回自身.方便链式操作
   */
  public S notBetween(Object start, Object end) {
    return notBetween(start, end, false);
  }

  /**设置单个字段的条件: LIKE
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S likeSQL(String value, Boolean isOr) {
    where.like(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: LIKE
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S likeSQL(String value) {
    return likeSQL(value, false);
  }

  /**设置单个字段的条件: LIKE
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S like(Object value, Boolean isOr) {
    return likeSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: LIKE
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S like(Object value) {
    return like(value, false);
  }

  /**设置单个字段的条件: NOT LIKE
   * @param value SQL语句 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notLikeSQL(String value, Boolean isOr) {
    where.notLike(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: NOT LIKE
   * @param value SQL语句 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S notLikeSQL(String value) {
    return notLikeSQL(value, false);
  }

  /**设置单个字段的条件: NOT LIKE
   * @param value 比较的值或字段名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notLike(Object value, Boolean isOr) {
    return notLikeSQL(utils.safeJSON(value), isOr);
  }

  /**设置单个字段的条件: NOT LIKE
   * @param value 比较的值或字段名;
   * @return 返回自身.方便链式操作
   */
  public S notLike(Object value) {
    return like(value, false);
  }

  /**设置单个字段的条件: IN
   * @param value 数组
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S in(Object[] value, Boolean isOr) {
    where.in(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: IN
   * @param value 数组
   * @return 返回自身.方便链式操作
   */
  public S in(Object[] value) {
    return in(value, false);
  }

  /**设置单个字段的条件: IN
   * @param value 数组
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S in(List<Object> value, Boolean isOr) {
    return value != null && value.size() > 0 ? in(value.toArray(), isOr) : where;
  }

  /**设置单个字段的条件: IN
   * @param value 数组
   * @return 返回自身.方便链式操作
   */
  public S in(List<Object> value) {
    return value != null && value.size() > 0 ? in(value.toArray(), false) : where;
  }

  /**设置单个字段的条件: NOT IN
   * @param value 数组
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notIn(Object[] value, Boolean isOr) {
    where.notIn(sqlName, value, isOr);
    return where;
  }

  /**设置单个字段的条件: NOT IN
   * @param value 数组
   * @return 返回自身.方便链式操作
   */
  public S notIn(Object[] value) {
    return notIn(value, false);
  }

  /**设置单个字段的条件: NOT IN
   * @param value 数组
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notIn(List<Object> value, Boolean isOr) {
    return value != null && value.size() > 0 ? notIn(value.toArray(), isOr) : where;
  }

  /**设置单个字段的条件: NOT IN
   * @param value 数组
   * @return 返回自身.方便链式操作
   */
  public S notIn(List<Object> value) {
    return value != null && value.size() > 0 ? notIn(value.toArray(), false) : where;
  }

  /**设置单个字段的条件: IN
   * 与in方法不同的是 接受参数sql为SQL语句
   * @param sql SQL语句
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S inSql(String sql, Boolean isOr) {
    where.inSql(sqlName, sql, isOr);
    return where;
  }

  /**设置单个字段的条件: IN
   * 与in方法不同的是 接受参数sql为SQL语句
   * @param sql SQL语句
   * @return 返回自身.方便链式操作
   */
  public S inSql(String sql) {
    return inSql(sql, false);
  }

  /**设置单个字段的条件: NOT IN
   * 与notIn方法不同的是 接受参数sql为SQL语句
   * @param sql SQL语句
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S notInSql(String sql, Boolean isOr) {
    where.notInSql(sqlName, sql, isOr);
    return where;
  }

  /**设置单个字段的条件: NOT IN
   * 与notIn方法不同的是 接受参数sql为SQL语句
   * @param sql SQL语句
   * @return 返回自身.方便链式操作
   */
  public S notInSql(String sql) {
    return notInSql(sql, false);
  }

  /**设置SQL语句条件
   * @param sql   要设置的条件sql;例如: id=abc;
   * 如果设置了别名,那么field必须跟上别名,或者加入前缀 #tableName#.;更改后为 #tableName#.`id`=abc;
   * 其中abc也可以是个表达式,如果是等于另一个表的值,也需要跟上其他表的别名;
   * @param isOr  与上一条件连接的逻辑,是否是OR连接;默认AND连接
   * @return 返回自身.方便链式操作
   */
  public S setWhere(String sql, Boolean isOr) {
    where.setWhere(sql, isOr);
    return where;
  }

  /**设置SQL语句条件
   * @param sql   要设置的条件sql;例如: id=abc;
   * 如果设置了别名,那么field必须跟上别名,或者加入前缀 #tableName#.;更改后为 #tableName#.`id`=abc;
   * 其中abc也可以是个表达式,如果是等于另一个表的值,也需要跟上其他表的别名;
   * @return 返回自身.方便链式操作
   */
  public S setWhere(String sql) {
    return setWhere(sql, false);
  }

}
